package com.example.skytakeoutserver.service

import com.example.serverbase.ext.Log
import com.example.skytakeoutserver.data.entity.User
import lombok.RequiredArgsConstructor
import lombok.extern.slf4j.Slf4j
import org.springframework.data.r2dbc.core.R2dbcEntityTemplate
import org.springframework.data.relational.core.query.Criteria
import org.springframework.data.relational.core.query.Query
import org.springframework.r2dbc.core.DatabaseClient
import org.springframework.stereotype.Service
import reactor.core.publisher.Mono
import java.time.LocalDateTime

@Service
@RequiredArgsConstructor
@Slf4j
class UserService
    (
    private val r2dbEntityTemplate: R2dbcEntityTemplate,
    private val databaseClient: DatabaseClient
) {
    /**
     * 统计用户
     */
    fun countByMap(begin: LocalDateTime?, end: LocalDateTime?): Mono<Long> {
        val sql = StringBuilder("SELECT COUNT(id) FROM user where 1=1")

        begin.let {
            sql.append(" and create_time = :begin")
        }

        end.let {
            sql.append(" and end_time = :end")
        }

        var spec = databaseClient
            .sql(sql.toString())

        begin?.let {
            spec = spec.bind("begin", it)
        }

        end?.let {
            spec = spec.bind("end", it)
        }

        return spec
            .map { row ->
                row.get("count(id)", Long::class.java)
            }
            .one()
            .map { sum -> sum ?: 0 }
            .onErrorResume { Mono.just(0) }
    }

    /**
     * 通过openId找到用户
     */
    fun findUserByOpenId(openId: String): Mono<User?> {
        val criteria = Criteria.where("open_id").`is`(openId)

        return r2dbEntityTemplate
            .selectOne<User>(
                Query.query(criteria), User::class.java
            ).doOnNext { user -> Log.info("User found in database: $user") }
            .doOnError { e -> Log.error("Error while searching user:", e.message) }
    }

}